#include <stdio.h>

#include "filepath-util.h"
#include "commonexception.h"
#include "bytearray.h"
#include "cxx-glibc-wrap.h"

int
main(int argc,char **argv)
{
    size_t maxSize = 0;
    const char *dir = nullptr;
    const char *dirNameTemplate = "rollXXXXXX";
    if (argc < 2) {
        printf("ERROR:%s 目录最大字节数 [目录名](若省略,则为当前目录)\n",argv[0]);
        return 1;
    } else {
        int sizeArg = atoi(argv[1]);
        if (sizeArg <= 0)
            THROW(EINVAL,"最大字节数不合法: %s!应大于 0",argv[1]);
        maxSize = sizeArg;

        if (argc >= 3)
            dir = argv[2];
    }
    if (dir == nullptr)
        dir = ".";
    printf("INFO;maxSize: %zu;dir: %s\n",maxSize,dir);

    char dirNameBuf[PATH_MAX];
    RawPath dirName {dirNameBuf,sizeof(dirNameBuf),dirNameTemplate};
    const size_t dirNameSize = dirName.size();
    size_t currentDirSize = 0;

    /* 根据 dirNameTemplate 生成随机目录名,并创建该目录,然后将目录名拷贝到 dirName 中.
     * 并将 currentDirSize 重置为 0.
     */
    auto roll = [&] () -> void {
        dirName.assign(dirNameTemplate);
        cxx_mkdtemp(dirName.data());
        currentDirSize = 0;
        printf("INFO:ROLL: 新目录名: %s\n",dirName.constData());
    };

    roll();
    auto dirTraverseF = [&] (const struct dirent &p) -> DirTraverseEnum {
        if (p.d_type != DT_REG) {
            printf("WARN: 跳过非 regular 文件: %s;其类型: %s\n",
                p.d_name,
                direntryType2Str(p.d_type));
            return DirTraverseEnum::CONTINUE;
        }

        size_t fileSize = getFileSize(p.d_name);
        if (currentDirSize + fileSize > maxSize)
            roll();
        currentDirSize += fileSize;
        dirName.append(p.d_name);
        cxx_rename(p.d_name,dirName.constData());
        dirName.resize(dirNameSize);
        printf("INFO: %s[%zu bytes] <- %s\n",dirName.constData(),currentDirSize,p.d_name);
        return DirTraverseEnum::CONTINUE;
    };

    dirTraverse(dir,DirTraverseEnum::DONTRECURSIVE,dirTraverseF);
    return 0;
}
